package com.rico.kok.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    //创建realm
    @Bean
    public ShiroRealm getShiroRealm(){
        return new ShiroRealm();
    }

    //创建安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(ShiroRealm shiroRealm){
        //声明安全管理器
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        //声明凭证匹配器
        HashedCredentialsMatcher hashedCredentialsMatcher=new HashedCredentialsMatcher();
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        hashedCredentialsMatcher.setHashIterations(789);

        //设置凭证匹配器
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher);

        //为安全管理器设置realm
        defaultWebSecurityManager.setRealm(shiroRealm);
        return defaultWebSecurityManager;
    }

    //创建shiroFilter
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){

        //声明一个shiro过滤器
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();

        //给安全管理器设置
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);

        //配置系统受限资源
        Map<String,String> map=new HashMap<>();
        map.put("/**","anon");
//        map.put("","authc");
        //默认的登陆界面为/login，可自定义界面
        shiroFilterFactoryBean.setLoginUrl("/login.html");

        //设置匹配规则
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        return shiroFilterFactoryBean;
    }

    /**
     * 开启aop注解支持
     * 即在controller中使用 @RequiresPermissions("user/userList")
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager){
        AuthorizationAttributeSourceAdvisor attributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //设置安全管理器
        attributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager);
        return attributeSourceAdvisor;
    }

    /**
     * 使用DefaultAdvisorAutoProxyCreator实现spring的自动代理
     * DefaultAdvisorAutoProxyCreator这个类功能更为强大，
     * 这个类的奇妙之处是他实现了BeanProcessor接口,
     * 当ApplicationContext读如所有的Bean配置信息后，
     * 这个类将扫描上下文，寻找所有的Advistor
     * (一个Advisor是一个切入点和一个通知的组成)，
     * 将这些Advisor应用到所有符合切入点的Bean中
     * @return
     */
    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
        return defaultAdvisorAutoProxyCreator;
    }
}
